﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Pigs.Enemies;
using Pigs.Weapons;

namespace pigs
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Mountain : Level
    {
        MountainBoss boss;
        Boolean bossPresent;
        Boolean bossDead;

        public Mountain(GameSettings set)
            : base(set)
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
            bossPresent = false;
            bossDead = false;
            levelName = "bc";
        }

        /// <summary>
        /// LoadContent images for gameplay
        /// </summary>
        public override void LoadContent()
        {
            wave = new Boolean[50];
            this.loadCommonContent();

            //load mountain
            Texture2D mountainObject = content.Load<Texture2D>("levels/demo/mountain2");
            Scenery mountainScenery = new Scenery(mountainObject, new Vector2(600, viewport.Height - mountainObject.Height));
            mountainScenery.initialize(-.4f, false);
            collidableBackground.Add(mountainScenery);

            mountainObject = content.Load<Texture2D>("levels/demo/mountain3");
            mountainScenery = new Scenery(mountainObject, new Vector2(1600, viewport.Height - mountainObject.Height));
            mountainScenery.initialize(-.4f, false);
            collidableBackground.Add(mountainScenery);

            mountainObject = content.Load<Texture2D>("levels/demo/mountain6flipped");
            mountainScenery = new Scenery(mountainObject, new Vector2(600, 0));
            mountainScenery.initialize(-.4f, true);
            collidableBackground.Add(mountainScenery);

            //load cloud
            Texture2D cityImage = content.Load<Texture2D>("levels/demo/clouds");
            Scenery city = new Scenery(cityImage, new Vector2(0, 0));
            city.initialize(-0.1f, false);
            background.Add(city);

            cityImage = content.Load<Texture2D>("levels/demo/cloudsflipped");
            city = new Scenery(cityImage, new Vector2(cityImage.Width - 1, 0));
            city.initialize(-0.1f, false);
            background.Add(city);
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            this.commonUpdate(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            //if game is active add pigs at given times
            if (IsActive)
            {
                if (levelTime > 3000 && !wave[1])
                {
                    addDrunk(50, 450);
                    addNinja(150, 100);
                    addNinja(100, 650);
                    wave[1] = true;
                }

                //start wave 0 a single normal pig
                if (levelTime > 10000 && !wave[2])
                {
                    addBasic(50, 200);
                    addBasic(150, 100);
                    addBasic(150, 200);
                    addBasic(150, 300);
                    addBasic(250, 100);
                    addBasic(250, 200);
                    addBasic(250, 300);
                    addSteel(300, 350);
                    addBunny(450, 300);
                    wave[2] = true;
                }

                if (levelTime > 20000 && !wave[3])
                {
                    addLeader(50, 350);
                    addMagic(300, 350);
                    wave[3] = true;
                }

                if (levelTime > 40000 && !wave[4])
                {
                    addSuicide(50, 300);
                    addBasic(200, 200);
                    addBasic(300, 250);
                    addBasic(300, 150);
                    addBasic(400, 100);
                    addBasic(400, 300);
                    addBunny(500, 650);
                    wave[4] = true;
                }

                if (levelTime > 47000 && !wave[5])
                {
                    addDrunk(50, 150);
                    addDrunk(50, 350);
                    wave[5] = true;
                }

                if (levelTime > 60000 && !wave[6])
                {
                    Texture2D mountainObject = content.Load<Texture2D>("levels/demo/tree3");
                    Scenery mountainScenery = new Scenery(mountainObject, new Vector2(viewport.Width + 10, viewport.Height - mountainObject.Height));
                    mountainScenery.initialize(-.4f, false);
                    collidableBackground.Add(mountainScenery);

                    for (int i = 0; i < 6; i++)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            addBasic(i * 80, j * 80);
                        }
                    }
                    addSuicide(450, 650);
                    wave[6] = true;
                }

                if (levelTime > 70000 && !wave[7])
                {
                    Texture2D mountainObject = content.Load<Texture2D>("levels/demo/tree1");
                    Scenery mountainScenery = new Scenery(mountainObject, new Vector2(viewport.Width + 10, viewport.Height - mountainObject.Height));
                    mountainScenery.initialize(-.4f, false);
                    collidableBackground.Add(mountainScenery);

                    addNinja(50, 50);
                    addNinja(50, 150);
                    addNinja(50, 250);
                    addSuicide(300, 0);
                    addSuicide(500, 0);
                    wave[7] = true;
                }

                if (levelTime > 76000 && !wave[8])
                {
                    Texture2D mountainObject = content.Load<Texture2D>("levels/demo/mountain4flipped");
                    Scenery mountainScenery = new Scenery(mountainObject, new Vector2(1500, 0));
                    mountainScenery.initialize(-.4f, true);
                    collidableBackground.Add(mountainScenery);

                    mountainObject = content.Load<Texture2D>("levels/demo/mountain5");
                    mountainScenery = new Scenery(mountainObject, new Vector2(1800, viewport.Height - mountainObject.Height));
                    mountainScenery.initialize(-.4f, false);
                    collidableBackground.Add(mountainScenery);

                    addSteel(50, 350);
                    wave[8] = true;
                }

                if (levelTime > 84000 && !wave[9])
                {
                    addBasic(80, 400);
                    addBasic(80, 480);
                    addBasic(80, 460);
                    addBasic(80, 470);
                    addBasic(80, 450);
                    addBasic(80, 440);
                    addBasic(80, 430);
                    addBasic(80, 420);
                    addBasic(80, 410);
                    wave[9] = true;
                }

                if (levelTime > 94000 && !wave[10])
                {
                    addBunny(750, 300);
                    wave[10] = true;
                }

                if (levelTime > 130000 && !wave[11])
                {
                    for (int i = 0; i < 6; i++)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            addBasic(i * 80, (j * 80)+300);
                        }
                    }
                    addMagic(10, 150);
                    addSuicide(600 , 350);

                    wave[11] = true;
                }

                if (levelTime > 150000 && !wave[12])
                {
                    foreach (Player p in players)
                    {
                        if (p.alive)
                        {
                            applyRumble(p, .2f, 0f, 5000);
                        }
                    }
                    Texture2D mountainBossText = content.Load<Texture2D>("enemies/bcBoss2");
                    boss = new MountainBoss(mountainBossText, new Vector2(viewport.Width + 10, 350), ScreenManager.GraphicsDevice, viewport.Width);
                    this.updateBackgrounds = false;
                    bossPresent = true;
                    wave[12] = true;
                }

                if (bossPresent)
                {
                    boss.Update(this.slops);
                    checkBossCollisions(gameTime);
                }

                if (bossDead && pigs.Count == 0)
                {
                    doEndGame(true);
                }
            }

            //tile the background clouds
            if (((int)background.Last().rectangle.Right) < (viewport.Width + 100))
            {
                Texture2D cityImage = content.Load<Texture2D>("levels/demo/clouds");
                Scenery city = new Scenery(cityImage, new Vector2((int)background.Last().rectangle.Right - 5, 0));
                city.initialize(-0.1f, false);
                background.Add(city);

                cityImage = content.Load<Texture2D>("levels/demo/cloudsflipped");
                city = new Scenery(cityImage, new Vector2((int)background.Last().rectangle.Right - 1, 0));
                city.initialize(-0.1f, false);
                background.Add(city);
            }
        }

        /// <summary>
        /// check if the boss is colliding with the players
        /// the players bullets and other pigs
        /// </summary>
        void checkBossCollisions(GameTime gameTime)
        {
            foreach (Player p in players)
            {
                if (p.checkCollision(boss))
                {
                    p.health = -1;
                    p.notHit = false;
                    destroyPlayer(p, gameTime);
                }

                foreach (Bullet b in p.bullets)
                {
                    if (b.checkCollision(boss))
                    {
                        if (boss.isEatingSlop)
                        {
                            boss.health -= b.damage / (settings.numberOfPlayers);
                            b.active = false;
                            Explosion e = new Explosion(explosionTexture, b.center(), .3f);
                            explosions.Add(e);
                        }
                        else
                        {
                            b.Reflect();
                        }
                    }
                }

                foreach (Flame f in p.flames)
                {
                    if (f.checkCollision(boss)) 
                    {
                        if (boss.isEatingSlop)
                        {
                            boss.health -= f.damage / (2 + settings.numberOfPlayers);
                        }
                        else
                        {
                            f.active = false;
                        }
                    }
                }
            }
            foreach (Pig p in pigs)
            {
                if (p.checkCollision(boss))
                {
                    wave[1] = true;
                }
            }
            // add new pigs
            if (pigs.Count < 3 && levelTime > 150000)
            {
                addBasic(100, 50);
                addBasic(100, 500);
                if (rand.Next(1, 3) == 1) addSuicide(150, 500);
                else addSuicide(150, 150);
            }

            //check health of boss
            if (boss.health <= 0)
            {
                getLowestPlayer().score += 10000;
                bossDead = true;
                boss.active = false;
                bossPresent = false;
                playSound(explosionSound);
                Explosion e = new Explosion(explosionTexture, boss.center(), 3);
                explosions.Add(e);
            }
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            this.commonDraw(gameTime);
            if (bossPresent && !bossDead)
            {
                boss.Draw(spriteBatch);
            }
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}
